package cn.jiangzeyin;

import java.security.SecureRandom;

/**
 * 随机数
 * Created by jiangzeyin on 2017/11/2.
 */
public final class RandomUtil {
    private static final SecureRandom random = new SecureRandom();
    private static byte[] seeds = random.generateSeed(20);
    private static final String base = "ABCDEFGHJKMNPQRSTWXYZabcdefhijkmnprstwxyz2345678";

    private static void seeds() {
        random.nextBytes(seeds);
        random.setSeed(seeds);
    }

    private RandomUtil() {
    }

    /**
     * 生成随机字符串
     * <p>
     * 默认去掉了容易混淆的字符oOLl,9gq,Vv,Uu,I1
     *
     * @param length 长度
     * @return 结果
     */
    public static String getRandomString(int length) {
        StringBuilder sb = new StringBuilder();
        for (int i = 0; i < length; i++) {
            int number = random.nextInt(base.length());
            sb.append(base.charAt(number));
        }
        seeds();
        return sb.toString();
    }

    /**
     * 随机生成指定长度的int 类型数字
     *
     * @param length 长度
     * @return 结果
     */
    public static int getRandomCode(int length) {
        if (length <= 0)
            return 0;
        if (length >= 10)
            throw new IllegalArgumentException("result data out");
        int min = length > 1 ? (int) Math.pow(10, length - 1) : 0;
        int max = (int) (Math.pow(10, length) - 1);
        return getRandom(min, max);
    }

    /**
     * 随机生成指定范围的随机数
     *
     * @param min 最小值
     * @param max 最大值
     * @return 结果
     */
    public static int getRandom(int min, int max) {
        if (max < min)
            throw new IllegalArgumentException("max < min");
        int val = random.nextInt(max) % (max - min + 1) + min;
        seeds();
        return val;
    }

    /**
     * 随机获取数组中一个元素
     *
     * @param objects 数组
     * @param <T>     泛型
     * @return object
     */
    public static <T> T getRandomArray(T[] objects) {
        if (objects == null || objects.length < 1)
            throw new IllegalArgumentException("objects is null");
        int index = random.nextInt(objects.length);
        seeds();
        return objects[index];
    }

    /**
     * 获取权重随机信息
     *
     * @param weights 权重数组
     * @return 返回随机结果后的下标
     */
    public static int getWeightRandom(int[] weights) {
        int weightSum = 0;
        for (int item : weights) {
            weightSum += item;
        }
        int n = random.nextInt(weightSum); // n in [0, weightSum)
        int m = 0;
        int result = 0;
        for (int i = 0, len = weights.length; i < len; i++) {
            int weight = weights[i];
            if (m <= n && n < m + weight) {
                result = i;
                break;
            }
            m += weight;
        }
        seeds();
        return result;
    }
}
